15 March 2004
When reviewing other people's code in the beginning, just skip anything with
a name like __get_attr__
or __iter__
. As with C,
C++ or Assembler, leading underscores usually indicate voodoo happens here,
so just make note of it for future explorations.
These bits are best avoided in the beginning.
They provide very powerful controls and offer rather elegant solutions for your top-level code. (Hint: you'll rarely see such functions or variables invoked directly, except usually by other routines with names involving leading underscores.)
As tutorials reveal certain methods such as __init__()
or
__str__()
, feel free to begin using them at that time.
Assigning values to class attributes (think: class member fields from C++, Java) is akin to creating static values.
Consider this example.
>>> class Breakfast: ... serving = ["spam & eggs", "toast"] ... skipping = [] ... ordered = None ...
If you have more than one instance of Breakfast, both will access the same lists.
>>> alice = Breakfast() >>> bob = Breakfast() >>>
Not only do they have identical contents...
>>> bob.serving == alice.serving True >>>
Both reference the exact same object!
>>> bob.serving is alice.serving True >>>
So then, appending the list of what Bob is skipping with his breakfast order effects Alice's too, even though it might be only Bob who wants spam & eggs without the spam.
>>> bob.skipping.append("spam") >>> alice.skipping ['spam'] >>>
The above subtlety applies to any pre-assigned value other than
None
.
>>> bob.ordered = 1 >>> print alice.ordered None >>>
As Python permits creating class attributes "on demand" unlike compiled object oriented languages, you can identify unshared fields by assigning a value of None (think: NULL).
class Breakfast: serving = ["spam & eggs", "toast"] skipping = None ordered = None def __init__(self): self.skipping = []
Or if you prefer more concise code:
class Breakfast: self.serving = ["spam & eggs", "toast"] def __init__(self): self.skipping = [] self.ordered = None
(And yes, there are ways to avoid inadvertently creating class variables, such as those created by typing errors in one's code. Though, a programming editor with word completion works even better. In Emacs, use ALT-/ much like using Tab key in Bash shell to attempt completing the current word.)